import _ from 'lodash'

export default {
    /**
     * 判断是否为JSON
     * @param {*} str
     * @returns
     */
    isJSON(str) {
        if (typeof str === 'string') {
            try {
                let obj = JSON.parse(str)
                if (typeof obj === 'object' && obj) {
                    return true
                } else {
                    return false
                }

            } catch (e) {
                return false
            }
        } else if (typeof str === 'object' && str) {
            return true
        }

    },
    /**
     * 字符串转JSON
     * @param {*} str
     * @returns
     */
    StringToJson(str) {
        if (typeof (str) == "string" && str.constructor === String && Object.prototype.toString.call(str) === "[object String]" && this.isJSON(str)) {
            return JSON.parse(str)
        }
        return str
    },
    /**
     * 判断对象是否为空
     * @param {*} obj
     * @returns
     */
    isEmptyObject(obj) {
        return Object.keys(obj).length === 0 && obj.constructor === Object;
    },
    /**
     * 判断是否为空
     * @param {*} obj
     * @returns
     */
    isEmpty(obj) {
        return _.isEmpty(obj)
    },
    /**
     * 深度克隆
     * @param {*} obj
     * @returns
     */
    cloneDeep(obj) {
        return _.cloneDeep(obj)
    },
    /**
     * 深度合并对象
     * @param {*} object
     * @param {*} source
     * @returns
     */
    merge(object, source) {
        return _.merge(object, source)
    },
    /**
     * 将响应式对象 变为普通对象
     * @param obj
     * @returns {{}|*}
     */
    deepToRaw(obj) {
        if (typeof obj !== 'object' || obj === null) {
            return obj;
        }
        if (Array.isArray(obj)) {
            return obj.map(this.deepToRaw);
        } else {
            const result = {};
            for (const key in obj) {
                result[key] = this.deepToRaw(obj[key]);
            }
            return result;
        }
    },
    /**
     * 由一个组件，向下找到最近的指定组件，根据组件名
     * @param {*} context
     * @param {*} ref
     * @returns
     */
    findComponentDownwardByRef(context, ref) {
        const childrens = context.$children;
        let children = null;

        if (childrens.length) {
            for (const child of childrens) {
                if (ref in child.$refs) {
                    children = child;
                    break
                } else {
                    children = this.findComponentDownwardByRef(child, ref);
                    if (children) break;
                }
            }
        }
        return children;
    },
    /**
     * 由一个组件，向下找到最近的指定组件，根据组件名
     * @param {*} context
     * @param {*} componentName
     * @returns
     */
    findComponentDownward(context, componentName) {
        const childrens = context.$children;
        let children = null;

        if (childrens.length) {
            for (const child of childrens) {
                const name = child.$options.name;

                if (name === componentName) {
                    children = child;
                    break;
                } else {
                    children = this.findComponentDownward(child, componentName);
                    if (children) break;
                }
            }
        }
        return children;
    },
    /**
     * 由一个组件，向下找到所有指定的组件，根据组件名
     * @param {*} context
     * @param {*} componentName
     * @returns
     */
    findComponentsDownward(context, componentName) {
        return context.$children.reduce((components, child) => {
            if (child.$options.name === componentName) components.push(child);
            const foundChilds = this.findComponentsDownward(child, componentName);
            return components.concat(foundChilds);
        }, []);
    },
    /**
     * 由一个组件，向上找到最近的指定组件,根据组件名
     * @param {*} context
     * @param {*} componentName
     * @returns
     */
    findComponentUpward(context, componentName) {
        let parent = context.$parent;
        let name = parent.$options.name;
        while (parent && (!name || [componentName].indexOf(name) < 0)) {
            parent = parent.$parent;
            if (parent) name = parent.$options.name;
        }
        return parent;
    },
    /**
     * 由一个组件，向上找到所有的指定组件,根据组件名
     * @param {*} context
     * @param {*} componentName
     * @returns
     */
    findComponentsUpward(context, componentName) {
        let parents = [];
        const parent = context.$parent;

        if (parent) {
            if (parent.$options.name === componentName) parents.push(parent);
            return parents.concat(this.findComponentsUpward(parent, componentName));
        } else {
            return [];
        }
    },

    /**
     * 日期格式化，年月日
     * @param {*} date 
     * @returns 
     */
    formatDate(date) {
        const y = date.getFullYear()
        const m = String(date.getMonth() + 1).padStart(2, '0') // 获取月份，补充为2位
        const d = String(date.getDate()).padStart(2, '0') // 获取日期，补充为2位
        return `${y}-${m}-${d}`
    },

    /**
     * 
     * @param {*} date 
     * @returns 
     */
    formatDateTime(date) {
        const y = date.getFullYear()
        const m = String(date.getMonth() + 1).padStart(2, '0') // 获取月份，补充为2位
        const d = String(date.getDate()).padStart(2, '0') // 获取日期，补充为2位
        const h = String(date.getHours()).padStart(2, '0')
        const minutes = String(date.getMinutes()).padStart(2, '0')
        const seconds = String(date.getSeconds()).padStart(2, '0')
        return `${y}-${m}-${d} ${h}:${minutes}:${seconds}`
    },

    formatMonth(date) {
        const y = date.getFullYear()
        const m = String(date.getMonth() + 1).padStart(2, '0') // 获取月份，补充为2位
        return `${y}-${m}`
    },
    getDaysAgo(days) {
        const date = new Date()
        date.setDate(new Date().getDate() - days)
        return this.formatDate(date)
    },

    getMonthAgo(months) {
        const date = new Date()
        date.setMonth(date.getMonth() - months)
        return this.formatMonth(date)
    },
    getMonthAgoDate(months) {
        const date = new Date()
        date.setMonth(date.getMonth() - months)
        return this.formatDate(date)
    }



}
